; Specify the class name of the window you want to get information about
windowClass := "Warcraft III"  ; Replace "Notepad" with the actual class name you are looking for
; windowClass := "Notepad"

; Define the OnExit subroutine to release the mouse cursor
; OnExit, ReleaseMouse

; System Resolution
sysWidth := 2560
sysHeight := 1080

; Specify the new position and size
newWidth := 1440
newHeight := 1080
newX := (sysWidth - newWidth) // 2
newY := (sysHeight = newHeight) // 2 + 7

; Offset to clip cursor
offset := 10
offsetTop := offset + 25

; Initialize variables to store window information
winTitle := ""
winID := ""
winPID := ""
winPosX := 0
winPosY := 0
winWidth := 0
winHeight := 0

; Replace the following with your actual program path, arguments, and working directory.
programPath := "d:\Warcraft III\Frozen Throne.exe"
;programPath := "d:\Warcraft III\Warcraft III.exe"
commandLineArgs := "-window"
workingDirectory := "d:\\Warcraft III\\"


CenterActiveWindow() {
    ; Get the active window's ID
    WinGet, activeWindowID, ID, A

    ; Get the size of the active window
    WinGet, windowSize, MinMax, ahk_id %activeWindowID%

    ; Get the screen resolution
    SysGet, screenRes, 76  ; 76 is the index for screen resolution (width)

    ; Calculate the new X position
    newX := (screenRes - windowSizeWidth) // 2

    ; The Y position can be adjusted as needed, here we center vertically as well
    newY := (A_ScreenHeight - windowSizeHeight) // 2

    ; Move and resize the window
    WinMove, ahk_id %activeWindowID%, , %newX%, %newY%, %windowSizeWidth%, %windowSizeHeight%
}

; Function to center the cursor if it goes outside the defined area
KeepCursorInWindow(minX, minY, boundaryX, boundaryY) {


    ; Get the current mouse position
    MouseGetPos, currentX, currentY
    ; MsgBox, Mouse Postition %currentX% %currentY%

    ; Determine the new mouse position if needed
    newX := currentX > boundaryX ? boundaryX : (currentX < minX ? minX : currentX)
    newY := currentY > boundaryY ? boundaryY : (currentY < minY ? minY : currentY)

    ; If the new X or Y is different from the current, move the mouse
    if (newX != currentX || newY != currentY) {
        MouseMove, newX, newY
    }
    
}

ClipCursor(rectX, rectY, rectRight, rectBottom) {
    ; Create a structure to hold the rectangle's coordinates.
    VarSetCapacity(rectangle, 16, 0)  ; RECT structure size: 4*4 = 16 bytes

    ; Set the coordinates of the rectangle.
    NumPut(rectX, rectangle, 0, "Int")    ; Left
    NumPut(rectY, rectangle, 4, "Int")    ; Top
    NumPut(rectRight, rectangle, 8, "Int") ; Right
    NumPut(rectBottom, rectangle, 12, "Int")  ; Bottom

    ; Call the ClipCursor function with the address of the rectangle structure.
    DllCall("user32.dll\ClipCursor", "Ptr", &rectangle)
}

; Check if the window with the specified class name exists and then activate it.
If WinExist("ahk_class " . windowClass) {
    WinActivate, ahk_class %windowClass%
} else {
  MsgBox, No window with the specified class name was found.
  ; Run, "d:\Warcraft III\Warcraft III.exe"

  ; Run the program with command line arguments, in a specific working directory, and wait for it to launch.
  Run, % programPath . " " . commandLineArgs, , WorkingDir %workingDirectory%

}

; wait for program to run
sleep 4000

; Detect the first window with the specified class
WinGet, winID, ID, ahk_class %windowClass%
if (winID = "") {
    MsgBox, No window found with ahk_class %windowClass%.
    return
}

; Get the process ID of the detected window
WinGet, winPID, PID, ahk_id %winID%

; Get the title of the detected window
WinGetTitle, winTitle, ahk_id %winID%

; Get the position and size of the detected window
WinGetPos, winPosX, winPosY, winWidth, winHeight, ahk_id %winID%

; Display the information in a message box
MsgBox, 4, Window Information,
(
    Window Information for ahk_class %windowClass%:`n`n
    Title: %winTitle%`n
    ID: %winID%`n
    Process ID: %winPID%`n
    Position (X, Y): (%winPosX%, %winPosY%)`n
    Size (Width x Height): %winWidth% x %winHeight%
)


; Call the MoveWindow API to set the position and size of the window
DllCall("MoveWindow", "UInt", winID, "Int", newX, "Int", newY, "Int", newWidth, "Int", newHeight, "Int", 1)

; Get the position after moved
WinGetPos, winPosX, winPosY, winWidth, winHeight, ahk_id %winID%

; Function to check if the window is closed
IsWindowClosed(windowClass) {
    ; Check if the window exists using the specified class
    return !WinExist("ahk_class " . windowClass)
}

windowRight := winPosX + winWidth
windowBottom := winPosY + winHeight

ClipCursor(winPosX + offset, winPosY + offsetTop, windowRight - offset, windowBottom - offset)

WinActivate, ahk_class %windowClass%

1::Numpad7
2::Numpad8
3::Numpad4
4::Numpad5
5::Numpad1
6::Numpad2

; Main loop to keep checking if the window is closed
Loop {
    ; Check if the window is closed
    if (IsWindowClosed(windowClass)) {
        ; Perform an action here, for example, show a message box
        MsgBox, The window with ahk_class %windowClass% is closed.
        
        DllCall("user32.dll\ClipCursor", "Ptr", 0)

        ; You can break the loop if you only want to check once
        ; Break the loop after performing the action
        break
    }

    ; Sleep for a short period before checking again to reduce CPU usage
    Sleep 60000  ; Sleep for 1000 milliseconds (1 second)
    
    ; If you want to perform a specific action repeatedly while the window is closed,
    ; you can place that code here and remove the 'break' statement.

}

; Optional: Add any cleanup or final actions here
return